package io.r2mo.test.common;

import io.r2mo.spi.SPI;
import io.r2mo.spring.junit5.AppBaseTestSupport;
import io.r2mo.test.common.domain.ProductCatEntity;
import io.r2mo.typed.json.JObject;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.stereotype.Component;
import org.springframework.test.context.TestPropertySource;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;
import java.util.Set;

/**
 * @author lang : 2025-09-07
 */
@SpringBootTest(classes = TestCommonApplication.class)
@Transactional
@TestPropertySource("classpath:env-test.properties")
@Component
@Slf4j
public class DbCountActTestCase extends AppBaseTestSupport<ProductCatEntity> {
    @BeforeEach
    public void before() {
        this.runOnce(() -> {
            final String sqlPrepare = "HFS/sql/productcat-data-insert.sql";
            this.executeFile(sqlPrepare);
            log.info("[ R2MO ] (0) DbCountActTestCase / 初始化数据完成，SQL：{} ", sqlPrepare);
        });
    }

    @Test
    public void testCountFull() {
        final Optional<Long> count = this.db().count();
        final Long countVal = count.orElse(0L);
        log.info("[ R2MO ] (1) testCount / 统计数据总数：{} ", countVal);
        Assertions.assertTrue(countVal > 0);
    }

    @Test
    public void testCountMarket() {

        // 提取 Type = MARKET 的数据
        final Optional<Long> countType = this.db().count("type", "MARKET");
        final Long countTypeVal = countType.orElse(0L);
        log.info("[ R2MO ] (1) testCount / 统计 Type=MARKET 的数据总数：{} ", countTypeVal);
        Assertions.assertTrue(countTypeVal > 0);
    }

    @Test
    public void testCountNonMarket() {
        // 使用复杂的 QTree 进行另外 Type 的统计
        final JObject condition = SPI.SPI_OBJECT.jsonObject();
        condition.put("type,i", Set.of("INTERNAL", "EXPERIMENTAL"));
        final Optional<Long> countType2 = this.db().count(condition);
        final Long countType2Val = countType2.orElse(0L);
        log.info("[ R2MO ] (1) testCount / 统计 Type=INTERNAL/EXPERIMENTAL 的数据总数：{} ", countType2Val);
    }

    @Test
    public void testCountMarketOr() {
        // 使用复杂的 QTree 进行另外 Type 的统计
        final JObject condition = SPI.SPI_OBJECT.jsonObject();
        condition.put("type", "MARKET");
        condition.put("$1", SPI.J()
            .put("type,<>", "EXTERNAL"));
        final Optional<Long> countType2 = this.db().count(condition);
        final Long countType2Val = countType2.orElse(0L);
        log.info("[ R2MO ] (1) testCount / 统计 Type=MARKET 或 Type<>EXTERNAL 的数据总数：{} ", countType2Val);
        Assertions.assertTrue(countType2Val > 0);
    }
}
